package org.reliablesource.jdt.linecounter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.reliablesource.jdt.model.IContributor;

/**
 * The activator class controls the plug-in life cycle
 */
public class ReliableJDTPlugin extends AbstractUIPlugin {

	// The plug-in ID
	public static final String PLUGIN_ID = "org.reliablesource.jdt"; //$NON-NLS-1$
	public static Map<String, IContributor> contributorsMap ;
	
	// The shared instance
	private static ReliableJDTPlugin plugin;
	
	/**
	 * The constructor
	 */
	public ReliableJDTPlugin() {
		plugin = this;
		contributorsMap = new HashMap<String, IContributor>();
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	/**
	 * Returns the shared instance
	 *
	 * @return the shared instance
	 */
	public static ReliableJDTPlugin getDefault() {
		return plugin;
	}

	/**
	 * Returns an image descriptor for the image file at the given
	 * plug-in relative path
	 *
	 * @param path the path
	 * @return the image descriptor
	 */
	public static ImageDescriptor getImageDescriptor(String path) {
		return imageDescriptorFromPlugin(PLUGIN_ID, path);
	}
	
	   /**
	    * Type independent way to reflectively invoke a method .
	    *
	    * @param _object - the object whose method you want.
	    * @param _methodNameExp - the name of the method.  This can be  in the form of a RegEx. (ie. get.*[Nn]ame), or not (ie. getName).
	    * @param _args - the argument list - in sequence.
	    *
	    * @return Object - the return value of the reflectively called method, if applicable.
	    * @throws IllegalArgumentException
	    * @throws RuntimeException
	    */
	   public static synchronized Object inputObjectMethodReflection(
	         Object _object, String _methodNameExp, Collection _args)
	         throws IllegalArgumentException, RuntimeException {
	      if(null == _args)
	         _args = new ArrayList();
	      
	      Class _cls = _object.getClass();
	      try {
	         Pattern _p = Pattern.compile(_methodNameExp);
	         Method[] _clsMethods = _cls.getMethods();
	         int _nMethods = _clsMethods.length;
	         for (int i = 0; i < _nMethods; i++) {
	            Matcher _matcher = _p.matcher(_clsMethods[i].getName());
	            if (_matcher.find()) {
	               Method _method = _cls.getMethod(_clsMethods[i].getName(),   _clsMethods[i].getParameterTypes());
	               return _method.invoke(_object, _args.toArray());
	            }
	         }
	         throw new IllegalArgumentException(_cls.getName()
	               + Messages.ReliableJDTPlugin_1 + _methodNameExp);
	      } catch (final NoSuchMethodException _nsme) {
	         throw new IllegalArgumentException(_cls.getName()
	               + Messages.ReliableJDTPlugin_1 + _methodNameExp);
	      } catch (final IllegalAccessException _iae) {
	         throw new IllegalArgumentException(
	               Messages.ReliableJDTPlugin_0 + _methodNameExp
	                     + Messages.ReliableJDTPlugin_4 + _cls.getName());
	      } catch (final InvocationTargetException _ite) {
	         throw new RuntimeException(_ite);
	      }
	   }
}
